package com.yonyou.crm.sys.user.ctrl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.yonyou.crm.bpub.pctpl.entity.EnumDescription;
import com.yonyou.crm.bpub.pctpl.entity.FieldsType;
import com.yonyou.crm.bpub.pctpl.entity.FormEnumFieldDescription;
import com.yonyou.crm.bpub.pctpl.entity.FormFieldDescription;
import com.yonyou.crm.bpub.pctpl.entity.FormRefFieldDescription;
import com.yonyou.crm.bpub.pctpl.entity.FormTplDescription;
import com.yonyou.crm.bpub.pctpl.entity.ListFieldDescription;
import com.yonyou.crm.bpub.pctpl.entity.ListTplDescription;
import com.yonyou.crm.common.base.ExcelExport;
import com.yonyou.crm.common.enumeration.entity.EnableStateEnum;
import com.yonyou.crm.common.exception.CrmMessageException;
import com.yonyou.crm.common.login.context.LoginContextConstant;
import com.yonyou.crm.common.page.entity.Page;
import com.yonyou.crm.common.rest.constant.HttpKeyConstant;
import com.yonyou.crm.common.rest.constant.PCCodeConstant;
import com.yonyou.crm.common.rest.util.RequestUtil;
import com.yonyou.crm.common.rest.util.ResponseUtil;
import com.yonyou.crm.csns.im.ctrl.ImCtrl;
import com.yonyou.crm.sys.org.entity.SysOrgVO;
import com.yonyou.crm.sys.org.rmitf.ISysOrgRmService;
import com.yonyou.crm.sys.role.entity.RoleVO;
import com.yonyou.crm.sys.role.rmitf.IRoleRmService;
import com.yonyou.crm.sys.user.entity.TypeEnum;
import com.yonyou.crm.sys.user.entity.UserVO;
import com.yonyou.crm.sys.user.rmitf.IUserRmService;
import com.yonyou.iuap.context.InvocationInfoProxy;

@RestController
@RequestMapping(value = "/sys/users")
public class UserCtrl {

	private static final Logger log = LoggerFactory.getLogger(UserCtrl.class);
	
	@Autowired
	private IUserRmService service;
	@Autowired
	private IRoleRmService roleService;
	@Autowired
	private ISysOrgRmService orgService;
	@Autowired
	private ImCtrl imCtrl;
	/**
	 * 查询用户
	 * @param request
	 * @param response
	 * @return
	 * @throws CrmMessageException 
	 */
	@RequestMapping(method = RequestMethod.GET)
	public Object list(HttpServletRequest request, HttpServletResponse response) throws CrmMessageException {

		JSONObject paramObj = RequestUtil.getParamObject(request);

		@SuppressWarnings("unchecked")
		Page<UserVO> userPage = service.page(getRequestPage(paramObj), (Map<String, Object>)paramObj.get("searchMap"));
		
		return ResponseUtil.getObject(userPage);
	}
	
	private Page<UserVO> getRequestPage(JSONObject paramObj) throws CrmMessageException {
		
		Integer page = paramObj.getInt(HttpKeyConstant.Page);
		Integer pageSize = paramObj.getInt(HttpKeyConstant.PageSize);
		
		if (page == null) {
        	throw new CrmMessageException(PCCodeConstant.ServerError, "page不能为空");
		}
		
		if (pageSize == null) {
			throw new CrmMessageException(PCCodeConstant.ServerError, "pageSize不能为空");
		}
		
		return new Page<UserVO>(page, pageSize);
	}

	/**
	 * 用户详情
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "{id}", method = RequestMethod.GET)
	public Object detail(@PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response) throws CrmMessageException {

		if (id == null) {
        	throw new CrmMessageException(PCCodeConstant.ServerError, "id不能为空");
		}		
		
		return ResponseUtil.getObject(service.detail(id));
	}
	
	
	/**
	 * 新增用户
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST)
	public Object insert(HttpServletRequest request, HttpServletResponse response) throws CrmMessageException {

		UserVO user = RequestUtil.getVO(request, UserVO.class);
		
		String validMsg = insertValidator(user);
		if (!validMsg.equals("")){
        	throw new CrmMessageException(PCCodeConstant.ServerError, validMsg);
		}
		
		user = service.insert(user);
		
		if (user.getId() == null) {
			throw new CrmMessageException(PCCodeConstant.ServerError, "获取自增主键为空");
		}
				
		return ResponseUtil.getObject(user);
	}

	private String insertValidator(UserVO user) {
		
		if (user == null) {
			return "转换实体失败";
		}
		
		if (StringUtils.isBlank(user.getName())) {
        	return  "姓名不能为空";
		}
		
		if (user.getOrgId() == null) {
        	return "所属公司不能为空";
		}
		
		if (user.getDeptId() == null) {
        	return "所属部门不能为空";
		}
		
		if (StringUtils.isBlank(user.getPhone())) {
			return "手机号不能为空";
		}
		
		return "";
	}
	
	/**
	 * 修改用户
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "{id}", method = RequestMethod.PUT)
	public Object update(@PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response) throws CrmMessageException {

		UserVO user = RequestUtil.getVO(request, UserVO.class);		
		if (user == null) {
        	throw new CrmMessageException(PCCodeConstant.ServerError, "转换实体失败");
		}
		
		user.setId(id);
		
		String validMsg = updateValidator(user);
		if (!validMsg.equals("")){
        	throw new CrmMessageException(PCCodeConstant.ServerError, validMsg);
		}

		UserVO newUser = service.update(user);
		try {
			imCtrl.updateVcard(newUser);
		} catch (Exception e) {
			//记录未同步的用户，使用其他方式同步
			log.error("user:"+JSONObject.fromObject(newUser).toString()+";reson:" + e.getMessage());
		}

		return ResponseUtil.getObject(newUser);
	}
	
	private String updateValidator(UserVO user) {
		
		if (user == null) {
			return "转换实体失败";
		}
		
		if (StringUtils.isBlank(user.getName())) {
        	return  "姓名不能为空";
		}
		
		if (user.getOrgId() == null) {
        	return "所属公司不能为空";
		}
		
		if (user.getDeptId() == null) {
        	return "所属部门不能为空";
		}
		
		if (StringUtils.isBlank(user.getPhone())) {
			return "手机号不能为空";
		}
		
		return "";
	}
	
	/**
	 * 批量删除用户
	 * @param id
	 * @param request
	 * @param response
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "batch", method = RequestMethod.DELETE)
	public Object batchDelete(HttpServletRequest request, HttpServletResponse response) throws CrmMessageException {
		
		JSONObject paramObj = RequestUtil.getParamObject(request);
		String idsStr = paramObj.getString("ids");		

		if (idsStr == null) {
			throw new CrmMessageException(PCCodeConstant.ServerError, "ids参数为空");
		}
		
		String[] idArray = idsStr.split(",");
		
		if (idArray.length == 0) {
			throw new CrmMessageException(PCCodeConstant.ServerError, "至少选中一条记录");
		}
		
		String message = service.batchDelete(idArray);
		Page<UserVO> voPage = service.page(getRequestPage(paramObj), (Map<String, Object>)paramObj.get("searchMap"));
		
		return ResponseUtil.getObject(voPage, message);
	}
	
	/**
	 * 批量停启用用户
	 * @param id
	 * @param request
	 * @param response
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "state", method = RequestMethod.PUT)
	public Object batchUpdateEnableState(HttpServletRequest request, HttpServletResponse response) throws CrmMessageException {
		
		JSONObject paramObj = RequestUtil.getParamObject(request);
		String idsStr = paramObj.getString("ids");		

		if (idsStr == null) {
			throw new CrmMessageException(PCCodeConstant.ServerError, "ids参数为空");
		}
		
		String[] idArray = idsStr.split(",");
		
		if (idArray.length == 0) {
			throw new CrmMessageException(PCCodeConstant.ServerError, "至少选中一条记录");
		}
		
		Integer enableState = paramObj.getInt("enableState");
		
		if (enableState == null) {
        	throw new CrmMessageException(PCCodeConstant.ServerError, "停启用状态不能为空");
		}
		
		String message = service.batchUpdateEnableState(idArray, enableState);
		Page<UserVO> voPage = service.page(getRequestPage(paramObj), (Map<String, Object>)paramObj.get("searchMap"));
				
		return ResponseUtil.getObject(voPage, message);
	}
	
	/**
	 * 是否为负责人
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "/respo", method = RequestMethod.GET)
	public Object isRespo(HttpServletRequest request, HttpServletResponse response) throws CrmMessageException {
						
		JSONObject paramObj = RequestUtil.getParamObject(request);
		Integer orgId = paramObj.getInt("orgId");

		int count = service.getUserCountByJob(orgId.longValue());
		if (count > 0) {
			throw new CrmMessageException(PCCodeConstant.ServerError, "负责人已存在");
		}
		
		return ResponseUtil.getObject();
	}

	@RequestMapping(value = "/template/list", method = RequestMethod.GET)
	public Object getListTplDescription(HttpServletRequest request, HttpServletResponse response) {

		List<ListFieldDescription> columns = new ArrayList<ListFieldDescription>();
		columns.add(new ListFieldDescription("姓名","name",null));
		columns.add(new ListFieldDescription("性别","genderName",null));
		columns.add(new ListFieldDescription("所属公司","orgName",null));
		columns.add(new ListFieldDescription("所属部门","deptName",null));
//		columns.add(new ListFieldDescription("职位","jobName",null));
		columns.add(new ListFieldDescription("手机","phone",null));
		columns.add(new ListFieldDescription("邮箱","email",null));
		columns.add(new ListFieldDescription("角色","roleName",null));
		
		Integer enableState = (Integer)RequestUtil.getObject(request, "enableState");
		if (enableState != null && enableState.intValue() == EnableStateEnum.DISABLE.getValue()) {
			columns.add(new ListFieldDescription("停用时间","enableTime","Date"));
		}
		
		columns.add(new ListFieldDescription("状态","enableStateName",null));
		ListTplDescription tplDes = new ListTplDescription(columns);
		return ResponseUtil.getObject(tplDes);
	}
	
	@RequestMapping(value = "/template/add", method = RequestMethod.GET)
	public Object getAddTplDescription(HttpServletRequest request, HttpServletResponse response) {
		
		FormTplDescription tplDes = new FormTplDescription(getFormList(true));
		return ResponseUtil.getObject(tplDes);
	}
	
	@RequestMapping(value = "/template/edit", method = RequestMethod.GET)
	public Object getEditTplDescription(HttpServletRequest request, HttpServletResponse response) {
		
		FormTplDescription tplDes = new FormTplDescription(getFormList(false));
		return ResponseUtil.getObject(tplDes);
	}
	
	private List<FormFieldDescription> getFormList(boolean isAdd) {
		
		List<FormFieldDescription> columns = new ArrayList<FormFieldDescription>();
		
		FormFieldDescription id = new FormFieldDescription("主键","id",FieldsType.String,"Input",false);
		columns.add(id);
		
		FormFieldDescription name = new FormFieldDescription("姓名","name",FieldsType.String,"Input");
		name.setNullAble(false);
		columns.add(name);
		
		FormFieldDescription phone = new FormFieldDescription("手机","phone",FieldsType.String,"Input");
		phone.setNullAble(false);
		phone.setValidateType("phone");
		columns.add(phone);
		
		FormFieldDescription email = new FormFieldDescription("邮箱","email",FieldsType.String,"Email");
		email.setValidateType("email");
		columns.add(email);
		
		FormFieldDescription genderName = new FormFieldDescription("性别","genderName",FieldsType.String,"Input",false);
		columns.add(genderName);
		List<EnumDescription> generEnum = new ArrayList<EnumDescription>();
		generEnum.add(new EnumDescription(1,"男"));
		generEnum.add(new EnumDescription(2,"女"));
		FormEnumFieldDescription gender = new FormEnumFieldDescription("性别","gender",FieldsType.Enum,"Ratio","",generEnum);
		gender.setDefaultValue("1");
		columns.add(gender);
		
		String defaultOrgId = null;
		String defaultOrgName = null;
		boolean orgDisabled = false;
		UserVO userVO = service.detail(new Long(InvocationInfoProxy.getParameter(LoginContextConstant.UserId)));
		if (userVO.getType().intValue() == TypeEnum.GSADMIN.getValue()) {
			defaultOrgId = InvocationInfoProxy.getParameter(LoginContextConstant.OrgId);
			
			SysOrgVO orgVO = orgService.getDetail(new Long(defaultOrgId));
			defaultOrgName = orgVO.getName();
			
			orgDisabled = true;
		}
		
		FormFieldDescription orgId = new FormFieldDescription("所属公司","orgId",FieldsType.String,"Input",false);
		orgId.setDefaultValue(defaultOrgId);
		columns.add(orgId);
		Map<String,String> orgMapper = new HashMap<String,String>();
		orgMapper.put("id", "orgId");
		orgMapper.put("name", "orgName");
		FormFieldDescription orgName = new FormRefFieldDescription("所属公司","orgName",FieldsType.Ref,"Company","公司",orgMapper);
		orgName.setNullAble(false);
		orgName.setDisabled(orgDisabled);
		orgName.setDefaultValue(defaultOrgName);
		columns.add(orgName);
		
		FormFieldDescription deptId = new FormFieldDescription("所属部门","deptId",FieldsType.String,"Input",false);
		Map<String,String> deptMapper = new HashMap<String,String>();
		deptMapper.put("id", "deptId");
		deptMapper.put("name", "deptName");
		FormFieldDescription deptName = new FormRefFieldDescription("所属部门","deptName",FieldsType.Ref,"Department","部门",deptMapper);
		deptName.setNullAble(false);
		if (orgDisabled) {
			deptName.setDisabled(false);
		}
		else {
			deptName.setDisabled(isAdd);
		}
		//参照关联
		deptName.setRelation("orgId");
		columns.add(deptId);
		columns.add(deptName);
		
		List<EnumDescription> roleEnum = new ArrayList<EnumDescription>();
		List<RoleVO> roleList = roleService.getRefList(null);
		for (RoleVO role : roleList) {
			roleEnum.add(new EnumDescription(role.getId().intValue(), role.getName()));
		}
		FormEnumFieldDescription role = new FormEnumFieldDescription("角色","roleId",FieldsType.Enum,"Enum","",roleEnum);
		columns.add(role);
		FormFieldDescription roleName = new FormFieldDescription("角色","roleName",FieldsType.String,"Input",false);
		columns.add(roleName);
		
		/*
		FormFieldDescription jobName = new FormFieldDescription("职务","jobName",FieldsType.String,"Input",false);
		columns.add(jobName);
		List<EnumDescription> jobEnum = new ArrayList<EnumDescription>();
		jobEnum.add(new EnumDescription(1,"员工"));
		jobEnum.add(new EnumDescription(2,"负责人"));
		jobEnum.add(new EnumDescription(3,"其他负责人"));
		FormEnumFieldDescription job = new FormEnumFieldDescription("职务","job",FieldsType.Enum,"Enum","",jobEnum);
		job.setNullAble(false);
		columns.add(job);
		*/
		
		if (!isAdd) {
			columns.add(new FormFieldDescription("状态","enableState",FieldsType.String,"Input",false));
		}
		
		return columns;
	}
	

	@RequestMapping(value = "export", method = RequestMethod.GET)
	public <T> Object exportExcel(HttpServletRequest request, HttpServletResponse response) throws IOException, CrmMessageException {
		Map<String, Object> param = new HashMap<>();
		List<UserVO> list = service.getUserListExport(param);
		String[] headers = {"Id","租户Id","公司I","部门Id","名称","性别","邮箱","手机号","密码","加密盐","职位","类型"};
		String[] fields = {"id","tenantId","orgId","deptId","name","genderName","email","phone","password","salt","jobName","typeName"};
		String title = "导出测试";
		String name = "人员导出.xls";
		   
		Map<String, Object> exportParam = new HashMap<>();
		exportParam.put("headers", headers);
		exportParam.put("fields", fields);
		exportParam.put("title", title);
		exportParam.put("name", name);
			   
		ExcelExport.exportDataToExcel(list, exportParam, response);
		return null;
	}
	
	/**
	 * 参照列表
	 * @param request
	 * @param response
	 * @return
	 * @throws CrmMessageException
	 */
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "ref", method = RequestMethod.GET)
	public Object getRefList(HttpServletRequest request, HttpServletResponse response) throws CrmMessageException {
		
		JSONObject paramObj = RequestUtil.getParamObject(request);
		
		Map<String, Object> searchMap = null;
		
		if (paramObj != null) {
			
			searchMap = (Map<String, Object>) paramObj.get("searchMap");
			
			//有分页信息返回分页列表
			if (paramObj.containsKey(HttpKeyConstant.Page) && paramObj.containsKey(HttpKeyConstant.PageSize)) {
				return ResponseUtil.getObject(service.getRefPage(getRequestPage(paramObj), searchMap));
			}
		}
		
		List<UserVO> voList = service.getRefList(searchMap);
		
		Page<UserVO> page = new Page<UserVO>();
		page.setData(voList);
		
		return ResponseUtil.getObject(page);
	}
	
	/**
	 * 分配角色
	 * @param request
	 * @param response
	 * @return
	 * @throws CrmMessageException
	 */
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "allocation", method = RequestMethod.PUT)
	public Object allocateRole(HttpServletRequest request, HttpServletResponse response) throws CrmMessageException {
		
		JSONObject paramObj = RequestUtil.getParamObject(request);
		String userIdStr = paramObj.getString("userIds");
		Integer roleId = paramObj.getInt("roleId");
		
		if (StringUtils.isBlank(userIdStr)) {
			throw new CrmMessageException("至少选中一个人员");
		}
		
		if (roleId == null) {
			throw new CrmMessageException("至少选中一个角色");
		}
				
		service.allocateRole(userIdStr.split(","), roleId.longValue());
		Page<UserVO> voPage = service.page(getRequestPage(paramObj), (Map<String, Object>)paramObj.get("searchMap"));
		
		return ResponseUtil.getObject(voPage, "分配成功。");
	}
	
	/**
	 * 修改密码
	 * @param request
	 * @param response
	 * @return
	 * @throws CrmMessageException
	 */
	@RequestMapping(value = "pwd", method = RequestMethod.PUT)
	public Object password(HttpServletRequest request, HttpServletResponse response) throws CrmMessageException {
		
		JSONObject paramObj = RequestUtil.getParamObject(request);
		Integer userId = paramObj.getInt("userId");
		String pwd = paramObj.getString("pwd");
		
		if (userId == null) {
			throw new CrmMessageException("用户id不能为空");
		}
		
		if (StringUtils.isBlank(pwd)) {
			throw new CrmMessageException("密码不能为空");
		}
		
		service.updatePassword(userId.longValue(), pwd);
						
		return ResponseUtil.getObject();
	}
}
